package com.kerrykidz.sales.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.kerrykidz.common.Constants;
import com.kerrykidz.common.ORDER_CONSTANTS;
import com.kerrykidz.common.service.ICommonService;
import com.kerrykidz.dao.model.GblPosDiscountEntity;
import com.kerrykidz.membership.dao.model.CusGuaEntity;
import com.kerrykidz.membership.dao.model.CusMemEntity;
import com.kerrykidz.membership.dao.model.GblCusCpndefEntity;
import com.kerrykidz.membership.service.IMemberService;
import com.kerrykidz.parreserve.dao.model.ParReserveEntity;
import com.kerrykidz.parreserve.service.IParReserveService;
import com.kerrykidz.sales.dao.model.PosOrderEntity;
import com.kerrykidz.sales.dao.model.PosOrderPaymentEntity;
import com.kerrykidz.sales.dao.model.PosOrderPrdEntity;
import com.kerrykidz.sales.service.IDiscountService;
import com.kerrykidz.sales.service.IOrderService;
import com.kerrykidz.sales.service.IPaymentService;
import com.kerrykidz.system.dao.model.SysAuditLogEntity;
import com.kerrykidz.system.service.ISysAuditLogService;
import com.kerrykidz.system.util.ConstantUtil;
import com.kerrykidz.system.util.UserUtil;
import com.kerrykidz.system.util.printReceipt.PrintHelper;
import com.kerrykidz.system.vo.UserInfo;
import com.rdp.framework.exception.RDPException;

/**
 * 
 * @Description 支付相关操作
 * @author QUINN
 * @date 2014年8月21日下午1:29:56
 */
@Controller
@RequestMapping("payment")
public class PaymentController {

	@Autowired
	private IOrderService orderService;

	@Autowired
	private IPaymentService paymentService;

	@Autowired
	private IMemberService memberService;

	@Autowired
	private IDiscountService discountService;

	@Autowired
	private ICommonService commonService;

	@Autowired
	private ISysAuditLogService isysAuditLogService;

	@Autowired
	private IParReserveService parReserveService;

	@RequestMapping(value = "skmx")
	public String skmx() {
		return "goods/skmx";
	}

	// 支付信息分页查询
	@RequestMapping(value = "paginateOrder", method = RequestMethod.POST)
	@ResponseBody
	public PosOrderEntity paginateOrder(PosOrderEntity pagebean) {
		UserInfo user = UserUtil.getUserFromSession();
		if (user != null)
			pagebean.setFkBranId(user.getBranId());
		pagebean = this.orderService.paginate(pagebean);
		return pagebean;
	}

	// 收银页面
	@RequestMapping(value = "shouyin")
	public String shouyin(@RequestParam("orderId") String orderId, ModelMap model) {
		PosOrderEntity order = this.orderService.findOrderByPk(orderId);
		List<PosOrderPrdEntity> products = this.orderService.findOrderPrdByOrderId(orderId);

		/*
		 * 如果是未预付状态
		 */
		if (ORDER_CONSTANTS.ORDER_STATUS_PREPAY.equals(order.getOrderStatus())) {
			model.put("isPrepay", true);
			model.put("order", order);
			model.put("products", products);
			return "goods/shouyin";
		}

		model.put("isPrepay", false);

		/*
		 * 是否有虚拟商品
		 */
		boolean hasVirtualGoods = !ORDER_CONSTANTS.ORDER_TYPE_PRODUCT.equals(order.getOrderType());

		String branId = UserUtil.getUserFromSession().getBranId();
		/*
		 * 如果有使用礼券
		 */
		if (StringUtils.isNotBlank(order.getGiftNo())) {
			String arr[] = order.getGiftNo().split(",");
			Map<String, String> nos = new HashMap<String, String>();
			for (String id_nos : arr) {
				String id_no[] = id_nos.split("_");
				if (id_no.length == 2) {
					nos.put(id_no[0], id_no[1]);
				}
			}
			if (nos.size() > 0) {
				String idArrs[] = new String[nos.size()];
				try {
					double giftPrice = this.discountService.getGiftNoPrice(nos.keySet().toArray(idArrs), branId);
					model.put("giftPrice", giftPrice);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}

		/*
		 * 有木有折扣
		 */

		if (StringUtils.isNotBlank(order.getFkDisId()))// 如果是整单折扣
		{
			GblPosDiscountEntity dis = this.discountService.findDiscountByPk(order.getFkDisId());
			if (dis != null) {
				model.put("zkje", order.getAmount() - order.getAmount() * dis.getDisValue());
			}
		} else// 如果不是整单折扣就去计算单个商品的折扣，disprice实际就是折扣之后的金额
		{
			double disPrice = 0;
			double hyxfzk = 0; // 会员续费折扣
			for (PosOrderPrdEntity prd : products) {
				// 会员续费折扣
				if (ORDER_CONSTANTS.EXTCPN_FLAG.equals(prd.getExtcpnFlag())) {
					hyxfzk += prd.getPrice() - prd.getPrice() * ORDER_CONSTANTS.MEM_RENEW_DIS;
				}
				disPrice += prd.getDisPrice();
			}
			disPrice += hyxfzk;
			model.put("hyxfzk", hyxfzk);
			model.put("zkje", order.getAmount() - disPrice);
		}

		/*
		 * 玩伴券金额
		 */
		double wbqje = 0d;
		for (PosOrderPrdEntity prd : products) {
			if (ORDER_CONSTANTS.COUPON_FLAG_ABLE.equals(prd.getCouponFlag())
					&& StringUtils.isNotBlank(prd.getFkBdycpnId())) {
				try {
					GblCusCpndefEntity cpn = this.commonService.findCouponsById(prd.getFkBdycpnId());
					if (cpn != null) {
						// 折扣
						if (Constants.CPNDEF_DISCOUNT_TYPE_ZK.equals(cpn.getDiscountType()))
							wbqje += prd.getPrice() - prd.getPrice() * cpn.getDiscountAmt();
						else if (Constants.CPNDEF_DISCOUNT_TYPE_DJ.equals(cpn.getDiscountType()))
							wbqje += cpn.getDiscountAmt();
					}
				} catch (RDPException e) {
					e.printStackTrace();
				}
			}
			// 是否含有虚拟商品
			if (!hasVirtualGoods)
				if (ORDER_CONSTANTS.ORDER_PRD_TYPE_CHARGE.equals(prd.getType())
						|| Constants.VIRTUAL_GOODS_CATE.contains(prd.getPrdCateId()))
					hasVirtualGoods = true;
		}

		model.put("hasVirtual", hasVirtualGoods);
		model.put("wbqje", wbqje);
		model.put("order", order);
		model.put("products", products);

		return "goods/shouyin";
	}

	/**
	 * 
	 * @Description 创建支付
	 * @param orderId
	 *            订单id
	 * @param payMethod
	 *            支付方式
	 * @param czxf
	 *            充值消费
	 * @param xj
	 *            现金
	 * @param yhk
	 *            银行卡
	 * @param memId
	 *            会员id
	 * @return
	 * @author QUINN
	 * @date 2014年8月11日下午3:29:45
	 */
	@RequestMapping(value = "addPayment", method = RequestMethod.POST)
	public synchronized String addPayment(@RequestParam("orderId") String orderId,
			@RequestParam("memPays") String memPays[], @RequestParam("isPrepay") boolean isPrepay,
			@RequestParam("xj") Double xj, @RequestParam("yhk") Double yhk, HttpServletRequest request,
			ModelMap model) {

		List<PosOrderPaymentEntity> payments = new ArrayList<PosOrderPaymentEntity>();

		UserInfo user = UserUtil.getUserFromSession();

		String errMsg = "errMsg";

		boolean hasErr = true;

		if (!hasErr) {
			model.put(errMsg, "金额输入错误!");
		}

		Date now = new Date();

		/*
		 * 余额支付
		 */
		for (String memPay : memPays) {
			String id_money[] = memPay.split("_");
			if (id_money.length == 3) {
				Double d = Double.valueOf(id_money[2]);
				if (d > 0) {
					PosOrderPaymentEntity payment = new PosOrderPaymentEntity();
					payment.setFkOrderId(orderId);
					payment.setPrepayFlag(isPrepay ? "1" : null);
					payment.setAmount(d);
					payment.setPayMethod(ORDER_CONSTANTS.PAY_METHOD_BALANCE);
					payment.setPayTime(now);
					payment.setFkPayer(id_money[0]);
					payment.setFkAccount(id_money[1]);
					payment.setFkPayee(user.getUserId());
					payment.setFkBranId(user.getBranId());
					payments.add(payment);
				}
			}
		}

		/*
		 * 现金支付
		 */
		if (xj != null) {
			PosOrderPaymentEntity xjp = new PosOrderPaymentEntity();
			xjp.setFkOrderId(orderId);
			xjp.setAmount(xj);
			xjp.setPayMethod(ORDER_CONSTANTS.PAY_METHOD_CASH);
			xjp.setPayTime(now);
			xjp.setFkPayee(user.getUserId());
			xjp.setFkBranId(user.getBranId());
			payments.add(xjp);
		}

		/*
		 * 银行卡支付
		 */
		if (yhk != null) {
			PosOrderPaymentEntity yhkp = new PosOrderPaymentEntity();
			yhkp.setFkOrderId(orderId);
			yhkp.setAmount(yhk);
			yhkp.setPayMethod(ORDER_CONSTANTS.PAY_METHOD_BANK);
			yhkp.setPayTime(now);
			yhkp.setFkPayee(user.getUserId());
			yhkp.setFkBranId(user.getBranId());
			payments.add(yhkp);
		}

		try {
			this.paymentService.createPayments(payments, orderId, isPrepay);

			PosOrderEntity order = new PosOrderEntity();
			order.setPkOrderId(orderId);
			if (isPrepay)
				order.setOrderStatus(ORDER_CONSTANTS.ORDER_STATUS_HAS_BEEN_PREPAY);
			else
				order.setOrderStatus(ORDER_CONSTANTS.ORDER_STATUS_HAS_BEEN_PAY);
			order.setModiTime(new Date());
			order.setModiBy(user.getUserId());
			this.orderService.updateOrder(order);

			order = new PosOrderEntity();
			order.setPkOrderId(orderId);

			/*
			 * 查找充值订单
			 */
			List<PosOrderPrdEntity> prds = this.orderService.findOrderPrdByOrderId(orderId);
			for (PosOrderPrdEntity prd : prds) {
				if (ORDER_CONSTANTS.ORDER_PRD_TYPE_CHARGE.equals(prd.getType()))
					this.paymentService.changeBalance(prd.getFkMemId(), prd.getDisPrice());
			}

			order = this.orderService.findOrderByPk(orderId);

			if (ORDER_CONSTANTS.ORDER_TYPE_PARTY.equals(order.getOrderType())) {
				ParReserveEntity parReserve = new ParReserveEntity();
				parReserve.setPkParresId(order.getFkParresId());
				parReserve.setResStatus(Constants.RESERVE_STATUS_TOBECONFIRM);
				parReserveService.updateParReserve(parReserve);

				// 原订单状态保持不变直至新订单预付成功后，原订单“取消”； by chenyu 2014-11-22
				parReserve = parReserveService.findParReserveById(order.getFkParresId());
				String fkParresid = parReserve.getFkPriorresId();
				if (StringUtils.isNotBlank(fkParresid)) {
					ParReserveEntity parReserveOld = new ParReserveEntity();
					parReserveOld.setPkParresId(fkParresid);
					parReserveOld.setResStatus(Constants.RESERVE_STATUS_CANCEL);
					parReserveService.updateParReserve(parReserveOld);

					PosOrderEntity ordercancel = new PosOrderEntity();
					ordercancel.setFkParresId(fkParresid);
					PosOrderEntity posOrder = orderService.findByCondition(ordercancel);
					if (null != posOrder) {
						posOrder.setOrderStatus(ORDER_CONSTANTS.ORDER_STATUS_CANCEL);
						orderService.updateOrder(posOrder);
					}
				}
			}

		} catch (Exception e) {
			e.printStackTrace();
			model.put(errMsg, e.getMessage());
			return shouyin(orderId, model);
		} finally {
			// 打印小票
			this.orderService.printOrderDetail(orderId);
		}
		return "redirect:/payment/symx.shtml";
	}

	// 收银明细页面
	@RequestMapping(value = "symx")
	public String symx(ModelMap model) {
		List<Map<String, Object>> list = this.paymentService.countTodayIncome(UserUtil.getUserFromSession()
				.getBranId());
		double xj = 0;
		double cz = 0;
		double yh = 0;
		for (Map<String, Object> map : list) {
			String k = (String) map.get("P");
			double v = Double.valueOf(map.get("V").toString());
			if (ORDER_CONSTANTS.PAY_METHOD_BALANCE.equals(k))
				cz = v;
			else if (ORDER_CONSTANTS.PAY_METHOD_BANK.equals(k))
				yh = v;
			else if (ORDER_CONSTANTS.PAY_METHOD_CASH.equals(k))
				xj = v;
		}
		model.put("xj", xj);
		model.put("cz", cz);
		model.put("yh", yh);

		UserInfo usr = UserUtil.getUserFromSession();

		SysAuditLogEntity sal = new SysAuditLogEntity();
		sal.setAuditTime(new Date());
		sal.setAuditType(ConstantUtil.AUDIT_TYPE_LOGIN);
		sal.setLogInfo(usr.getName() + ConstantUtil.AUDIT_TYPE_LOGINFO);
		sal.setFkBranId(usr.getBranId());
		sal.setModiBy(usr.getUserId());
		sal.setModiTime(new Date());
		try {
			isysAuditLogService.saveSysAuditLogEntity(sal);
		} catch (RDPException e) {
			e.printStackTrace();
		}

		return "goods/symx";
	}

	// 分页查询支付信息
	@RequestMapping(value = "paginate")
	@ResponseBody
	public PosOrderPaymentEntity paginate(PosOrderPaymentEntity payment) {
		payment.setOstatus(ORDER_CONSTANTS.ORDER_STATUS_HAS_BEEN_PAY);
		payment = this.paymentService.paginate(payment);
		return payment;
	}

	// 根据指纹获取用户信息
	@RequestMapping(value = "findCusMemByFinger", method = RequestMethod.POST)
	@ResponseBody
	public Object findCusMemByFinger(@RequestParam("finger") String finger) {
		Object result[] = new Object[2];
		List<CusMemEntity> mems = new ArrayList<CusMemEntity>();
		try {
			Object o = this.memberService.findFingerprint(finger);
			if (o != null) {
				if (o instanceof CusMemEntity) {
					CusMemEntity c = (CusMemEntity) o;
					mems.add(c);
					result[0] = c.getPkMemId();
				} else if (o instanceof CusGuaEntity) {
					CusGuaEntity c = (CusGuaEntity) o;
					mems.addAll(this.memberService.findByGua((c).getPkGuaId()));
					result[0] = c.getPkGuaId();
				}
			}
		} catch (RDPException e) {
			e.printStackTrace();
		}

		for (CusMemEntity mem : mems)
			mem.getAge();

		result[1] = mems;

		return result;
	}

	// 去退款页面
	@SuppressWarnings("unchecked")
	@RequestMapping(value = "refundMoney", method = RequestMethod.GET)
	public String refundMoney(@RequestParam("orderId") String orderId, ModelMap model) {
		shouyin(orderId, model);

		PosOrderEntity order = (PosOrderEntity) model.get("order");
		double ytje = 0;

		/*
		 * 如果是退会
		 */
		if (ORDER_CONSTANTS.ORDER_TYPE_VIP.equals(order.getOrderType())
				|| ORDER_CONSTANTS.ORDER_TYPE_RECHARGE.equals(order.getOrderType())) {
			ytje = order.getAmount();
			List<PosOrderPrdEntity> products = (List<PosOrderPrdEntity>) model.get("products");
			String memId = null;
			for (PosOrderPrdEntity prd : products)
				if (ORDER_CONSTANTS.ORDER_PRD_TYPE_CHARGE.equals(prd.getType()))
				{
					if (StringUtils.isNotBlank(prd.getFkMemId())) {
						memId = prd.getFkMemId();
						break;
					}
				}
			if (memId != null) {
				PosOrderPaymentEntity payment = this.paymentService.getMemLastPayment(memId);
				if (payment != null) {
					if (ORDER_CONSTANTS.PAY_METHOD_BANK.equals(payment.getPayMethod())) {
						model.put("yinhangka", order.getAmount());
					} else
						model.put("xianjin", order.getAmount());
				}
			}
			model.put("vir", true);
		}
		else // 不是退会
		{
			List<PosOrderPaymentEntity> payments = null;
			try {
				payments = this.paymentService.findByThOrderPk(orderId);
			} catch (Exception e) {
				e.printStackTrace();
			}

			if (payments != null) {
				List<PosOrderPaymentEntity> yue = null;
				PosOrderPaymentEntity xianjin = null;
				PosOrderPaymentEntity yinhangka = null;

				for (PosOrderPaymentEntity p : payments) {
					ytje += p.getAmount();
					if (p.getPayMethod().equals(ORDER_CONSTANTS.PAY_METHOD_BALANCE)) {
						yue = yue == null ? new ArrayList<PosOrderPaymentEntity>() : yue;
						yue.add(p);
					} else if (p.getPayMethod().equals(ORDER_CONSTANTS.PAY_METHOD_CASH)) {
						if (xianjin == null)
							xianjin = p;
						else
							xianjin.setAmount(xianjin.getAmount() + p.getAmount());
					} else if (p.getPayMethod().equals(ORDER_CONSTANTS.PAY_METHOD_BANK)) {
						if (yinhangka == null)
							yinhangka = p;
						else
							yinhangka.setAmount(yinhangka.getAmount() + p.getAmount());
					}
				}

				model.put("yue", yue);
				model.put("xianjin", xianjin);
				model.put("yinhangka", yinhangka);
			}
			model.put("vir", false);
		}
		model.put("ytje", ytje);
		return "goods/refundMoney";
	}

	@RequestMapping(value = "refundMoney", method = RequestMethod.POST)
	public String refundMoneyPost(@RequestParam("orderId") String orderId, @RequestParam("yue") String yue[],
			@RequestParam("xj") Double xj, @RequestParam("yhk") Double yhk) {

		UserInfo user = UserUtil.getUserFromSession();

		List<PosOrderPaymentEntity> payments = new ArrayList<PosOrderPaymentEntity>();
		if (yue != null)
			for (String y : yue) {
				String ys[] = y.split("_");
				if (ys.length == 2) {
					PosOrderPaymentEntity payment = new PosOrderPaymentEntity();
					payment.setFkOrderId(orderId);
					payment.setAmount(-Math.abs(Double.parseDouble(ys[0])));
					payment.setPayMethod(ORDER_CONSTANTS.PAY_METHOD_BALANCE);
					payment.setFkAccount(ys[1]);
					payment.setPayTime(new Date());
					payment.setFkPayee(user.getUserId());
					payment.setFkBranId(user.getBranId());
					payments.add(payment);
				}
			}

		if (xj != null && xj > 0) {
			PosOrderPaymentEntity payment = new PosOrderPaymentEntity();
			payment.setFkOrderId(orderId);
			payment.setAmount(-Math.abs(xj));
			payment.setPayMethod(ORDER_CONSTANTS.PAY_METHOD_CASH);
			payment.setPayTime(new Date());
			payment.setFkPayee(user.getUserId());
			payment.setFkBranId(user.getBranId());
			payments.add(payment);
		}

		if (yhk != null && yhk > 0) {
			PosOrderPaymentEntity payment = new PosOrderPaymentEntity();
			payment.setFkOrderId(orderId);
			payment.setAmount(-Math.abs(yhk));
			payment.setPayMethod(ORDER_CONSTANTS.PAY_METHOD_BANK);
			payment.setPayTime(new Date());
			payment.setFkPayee(user.getUserId());
			payment.setFkBranId(user.getBranId());
			payments.add(payment);
		}

		try {
			this.paymentService.createPayments(payments, orderId, false);
			PosOrderEntity order = new PosOrderEntity();
			order.setPkOrderId(orderId);
			order.setOrderStatus(ORDER_CONSTANTS.ORDER_STATUS_HAS_BEEN_PAY);
			this.orderService.updateOrder(order);

			List<PosOrderPrdEntity> prds = this.orderService.findOrderPrdByOrderId(orderId);
			for (PosOrderPrdEntity prd : prds) {
				if (ORDER_CONSTANTS.ORDER_PRD_TYPE_CHARGE.equals(prd.getType()))
					this.paymentService.changeBalance(prd.getFkMemId(), -(Math.abs(prd.getDisPrice())));
			}

			this.memberService.createMemHis(orderId);

		} catch (Exception e) {
			e.printStackTrace();
		}

		return "redirect:/payment/symx.shtml";
	}

	@RequestMapping(value = "printPaymentDetail", method = RequestMethod.POST)
	public void printPaymentDetail(@RequestParam("xj") final String xj, @RequestParam("yh") final String yh,
			@RequestParam("cz") final String cz, @RequestParam("lj") final String lj) {
		new Thread() {
			@Override
			public void run() {
				PrintHelper.printPaymentDetail(xj, yh, cz, lj);
			}
		}.start();
	}

}
